import React from "react";
import {VJsonComponent} from "../factory";
import {DataComponentProp, DataComponentState, VJsonDataComponentBase} from "../datasource";
import _ from "lodash";
import {Form as AntdForm, Spin, Transfer as AntdTransfer} from 'antd'
import {YvanEvent} from "../types";
import {YvanEventBind} from "..";
import * as Extend from "../extend";
import {IReactionDisposer} from "mobx/lib/core/reaction";
import {autorun, toJS} from "mobx";
import {NamePath} from "rc-field-form/lib/interface";

export interface TransferVJsonDataProp extends DataComponentProp<Transfer> {
    /**
     * 是否可见
     */
    visible?: boolean
    bind?: string
    height?: number
    itemWidth?: number
    disabled?: boolean
    footer?: React.ReactNode
    listStyle?: object
    operations: string[]
    oneWay?: boolean
    pagination?: boolean | { pageSize: number }
    selectedKeys?: string[]
    showSearch?: boolean
    showSelectAll?: boolean
    titles?: string[]
    onChange?: YvanEvent<Transfer>
    onScroll?: YvanEvent<Transfer>
    onSelectChange?: YvanEvent<Transfer>
    renderFooter?: YvanEvent<Transfer>
}

export interface TransferState extends TransferVJsonDataProp, DataComponentState {
    targetKeys: any[]
}

@VJsonComponent({
    view: 'transfer'
})
export default class Transfer extends VJsonDataComponentBase<Transfer, TransferVJsonDataProp, TransferState> {
    static defaultProps = {
        ...VJsonDataComponentBase.defaultProps,
        visible: true,
        labelField: 'title',
        idField: 'key',
        data: []
    }

    formItemName!: NamePath
    valueWatcherDisposer?: IReactionDisposer

    constructor(props: any) {
        super(props);

        let value = []
        this.formItemName = props.vjson.bind ? props.vjson.bind :
            props.$default.$parentBind + '.' + props.vjson.bindChild

        if (!this.formItemName) {
            this.formItemName = _.uniqueId('name_')
        }

        _.defaults(
            props.vjson,
            Transfer.defaultProps
        )
    }

    componentDidMount() {
        super.componentDidMount();
        const me = this

        this.valueWatcherDisposer = autorun(() => {
            let value = _.get(me.props.$context.scopeInstance, me.formItemName)
            if (Extend.isDebugMode()) {
                console.log('ValueWatch', me.toString(), '.targetKeys', '=', value)
            }

            this.setState({
                targetKeys: toJS(value)
            })
        });
    }

    componentWillUnmount() {
        super.componentWillUnmount();

        if (this.valueWatcherDisposer) {
            this.valueWatcherDisposer();
        }
    }

    protected filterOption(filterWord: any, row: any) {
        if (!filterWord) {
            return true
        }

        const {title, key} = row

        const pyKey = Extend.getPinyin(title).toLowerCase()
        return (
            pyKey.indexOf(filterWord.toLowerCase()) >= 0 || key.indexOf(filterWord) >= 0
        )
    }

    selectAllLabels(): React.ReactNode[] {
        return []
    }

    render() {
        if (!this.props.vjson.visible) {
            return null
        }

        let dataSource: any
        if (this.props.vjson.labelField === 'title' && this.props.vjson.idField === 'key') {
            dataSource = this.data

        } else {
            dataSource = _.map(this.data, (row) => {
                return {
                    title: this.props.vjson.labelField ? row[this.props.vjson.labelField] : row,
                    key: this.props.vjson.idField ? row[this.props.vjson.idField] : row
                }
            })
        }

        return (
            // @ts-ignore
            <Spin spinning={this.loading} key={this.key} view_id={this.key} aria-roledescription={this.view}>
                <AntdTransfer
                    showSearch={this.props.vjson.showSearch}
                    filterOption={this.filterOption.bind(this)}

                    dataSource={dataSource}
                    disabled={this.props.vjson.disabled}
                    listStyle={toJS(this.props.vjson.listStyle)}
                    operations={this.props.vjson.operations}
                    oneWay={this.props.vjson.oneWay}
                    titles={this.props.vjson.titles}
                    pagination={this.props.vjson.pagination}
                    selectedKeys={this.props.vjson.selectedKeys}
                    showSelectAll={this.props.vjson.showSelectAll}
                    // @ts-ignore
                    selectAllLabels={this.selectAllLabels.bind(this)}
                    targetKeys={this.props.vjson.targetKeys}
                    // @ts-ignore
                    render={item => item.title}
                    onChange={YvanEventBind(this.props.vjson.onChange, this)}
                    onScroll={YvanEventBind(this.props.vjson.onScroll, this)}
                    onSelectChange={YvanEventBind(this.props.vjson.onSelectChange, this)}
                    // @ts-ignore
                    footer={YvanEventBind(this.props.vjson.renderFooter, this)}
                />
            </Spin>
        )
    }
}